#ifndef ROUTER_H
#define ROUTER_H

#include <functional>
#include <memory>
#include <regex>

#include "../http/HttpRequest.h"
#include "../http/HttpResponse.h"
#include "./RouterHandler.h"

// 可以优化将静动态路由键统一等；而分开逻辑会好写些
// 这里设计将静态路由作为“默认/传统”方式，动态路由作为“新特性”
class Router
{
public:
    // 路由键：请求方法+路径
    struct Key
    {
        HttpRequest::Method method;
        std::string path;

        bool operator==(const Key &other) const // 用于比较
        {
            return method == other.method && path == other.path;
        }
    };

    // std::unordered_map<>记录需要自定义Key如何哈希
    struct KeyHash
    {
        // size_t operator()(const Key &key) const
        // {
        //     return std::hash<int>{}(static_cast<int>(key.method)) ^
        //            std::hash<std::string>{}(key.path);
        // }
        size_t operator()(const Key &key) const
        {
            size_t methodHash = std::hash<int>{}(static_cast<int>(key.method)); // 临时对象计算哈希
            size_t pathHash = std::hash<std::string>{}(key.path);
            return methodHash * 31 + pathHash; // 质数混淆值减少哈希冲突
        }
    };

    // 路由值：
    // 1.处理函数：函数式，std::function<void(const HttpRequest &, HttpResponse *)>，适用于简单处理
    // 2.处理指针：对象式，std::shared_ptr<RouterHandler>（继承RouterHandler），适用于复杂处理
    using HandlerFunc = std::function<void(const HttpRequest &, HttpResponse *)>;
    using HandlerPtr = std::shared_ptr<RouterHandler>;

    // 注册静态路由
    void registerHandlerFunc(HttpRequest::Method method, const std::string &path, const HandlerFunc &value)
    {
        Key key{method, path};
        this->handlerFuncs_[key] = std::move(value);
    }
    void registerHandlerPtr(HttpRequest::Method method, const std::string &path, HandlerPtr value) // 指针直接传
    {
        Key key{method, path};
        this->handlerPtrs_[key] = std::move(value);
    }

    // 注册动态路由
    void addRegexHandlerFunc(HttpRequest::Method method, const std::string &path, const HandlerFunc &handlerFunc)
    {
        std::regex pathRegex = this->pathToRegex(path);
        this->regexhandlerFuncs_.emplace_back(method, pathRegex, handlerFunc);
    }
    void addRegexHandlerPtr(HttpRequest::Method method, const std::string &path, HandlerPtr handlerPtr)
    {
        std::regex pathRegex = this->pathToRegex(path);
        this->regexhandlerPtrs_.emplace_back(method, pathRegex, handlerPtr);
    }

    // 处理请求
    bool route(const HttpRequest &req, HttpResponse *res);

private:
    // 路径模式->正则表达式模式，支持匹配任意路径参数
    // /user/:id -> ^/user/([^/]+)$
    // ()捕获组；[]+匹配一个或多个；^/除了正斜杠外的所有字符
    std::regex pathToRegex(const std::string &pathPattern)
    {
        std::string regexPattern = "^" + std::regex_replace(pathPattern, std::regex(R"(/:([^/]+))"), R"(/([^/]+))") + "$";
        return std::regex(regexPattern);
    }

    // 提取路径参数
    void extractPathParameters(const std::smatch &match, HttpRequest &request)
    {
        for (size_t i = 1; i < match.size(); ++i) // 索引0是捕获的所有，从1开始是每个
        {
            request.setPathParameters("param" + std::to_string(i), match[i].str());
        }
    }

private:
    // 静态路由精准匹配
    std::unordered_map<Key, HandlerFunc, KeyHash> handlerFuncs_;
    std::unordered_map<Key, HandlerPtr, KeyHash> handlerPtrs_;

    // 另一种记录方式
    // 路由键值：请求方法+路径模式+处理函数/指针
    struct KeyValueFunc
    {
        HttpRequest::Method method_;
        std::regex pathRegex_;
        HandlerFunc handerFunc_;

        KeyValueFunc(HttpRequest::Method method, std::regex pathRegex, const HandlerFunc &handerFunc)
            : method_(method), pathRegex_(pathRegex), handerFunc_(std::move(handerFunc)) {}
    };

    struct KeyValuePtr
    {
        HttpRequest::Method method_;
        std::regex pathRegex_;
        HandlerPtr handlerPtr_;

        KeyValuePtr(HttpRequest::Method method, std::regex pathRegex, HandlerPtr handlerPtr)
            : method_(method), pathRegex_(pathRegex), handlerPtr_(std::move(handlerPtr)) {}
    };

    // 动态路由正则匹配
    std::vector<KeyValueFunc> regexhandlerFuncs_;
    std::vector<KeyValuePtr> regexhandlerPtrs_;
};

#endif // ROUTER_H